package cn.org.xwb.bookmall.admin.controller;

import cn.org.xwb.bookmall.admin.annotation.IsLoginParam;
import cn.org.xwb.bookmall.model.constant.AccountConst;
import cn.org.xwb.bookmall.model.po.AllowMail;
import cn.org.xwb.bookmall.model.po.Orders;
import cn.org.xwb.bookmall.model.po.Product;
import cn.org.xwb.bookmall.model.po.ProductOptions;
import cn.org.xwb.bookmall.model.service.impl.OrdersServiceImpl;
import cn.org.xwb.bookmall.model.service.impl.ProductOptionsServiceImpl;
import cn.org.xwb.bookmall.model.service.impl.ProductServiceImpl;
import cn.org.xwb.bookmall.model.vo.OrderVo;
import cn.org.xwb.bookmall.model.vo.ProductVo;
import cn.org.xwb.common.encrypt.annotation.des.DesEn;
import cn.org.xwb.common.encrypt.annotation.rsa.RsaDe;
import cn.org.xwb.common.encrypt.annotation.rsa.RsaDeParam;
import cn.org.xwb.common.encrypt.constant.EncryptConstant;
import cn.org.xwb.common.error.annotation.ServerErrorCatch;
import cn.org.xwb.common.model.vo.RespResult;
import cn.org.xwb.common.page.dto.PageResult;
import cn.org.xwb.common.page.utils.PageUtil;
import cn.org.xwb.common.valid.annotation.nu.NotNull;
import cn.org.xwb.common.valid.annotation.nu.NotNullParam;
import cn.org.xwb.common.valid.annotation.str.StrMaxLen;
import cn.org.xwb.common.valid.annotation.str.StrNotNull;
import cn.org.xwb.common.valid.annotation.str.StrNotNullParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/order")
public class AdminOrderController {

    @Autowired
    private OrdersServiceImpl ordersService;

    @Autowired
    private ProductServiceImpl productService;

    @Autowired
    private ProductOptionsServiceImpl productOptionsService;

    @GetMapping("/page")
    @ServerErrorCatch
    @StrNotNull
    @RsaDe
    @IsLoginParam
    @DesEn
    public RespResult<Object> getOrderPage(
            @RequestParam(EncryptConstant.DES_KEY_PARAM_NAME)
            @StrNotNullParam @RsaDeParam
            String desKey,
            @RequestParam(AccountConst.ACCOUNT_PARAM_NAME)
            @StrNotNullParam @RsaDeParam
            String account,
            @RequestParam(value = "kw", required = false) @RsaDeParam
            String kw,
            @RequestParam(value = "status", required = false)
            Integer status,
            @RequestParam("current")
            Integer current,
            @RequestParam("pageSize")
            Integer pageSize
    ) {
        // 从缓存中获取全部的用户订单信息
        List<OrderVo> orderVoList = ordersService.findFromCache();
        // 根据用户订单的创建时间进行逆序排序
        Collections.reverse(orderVoList);
        // 条件过滤
        // 根据订单状态进行筛选过滤
        if (Objects.nonNull(status)) {
            orderVoList = orderVoList.stream().filter(orderVo -> orderVo.getStatus() == status).toList();
        }
        // 根据物流单号或发货地址或收货地址或收货人姓名或书籍商品名称或书籍商品选项名称对用户订单进行筛选过滤
        if (Objects.nonNull(kw) && kw.length() > 0) {
            orderVoList = orderVoList.stream().filter(
                    orderVo -> {
                        return (Objects.nonNull(orderVo.getLogistics()) && orderVo.getLogistics().contains(kw))
                                || (orderVo.getDelivery() + orderVo.getAddressFrom()).contains(kw)
                                || orderVo.getTitle().contains(kw)
                                || orderVo.getProductOptionName().contains(kw)
                                || orderVo.getName().contains(kw)
                                || (orderVo.getProvince() + orderVo.getCity() + orderVo.getCounty() + orderVo.getAddress()).contains(kw);
                    }
            ).toList();
        }
        // 对用户订单进行分页
        // 页数
        Integer pageCnt = PageUtil.getPageCnt(orderVoList.size(), pageSize);
        // 分页数据
        orderVoList = ((List<OrderVo>) PageUtil.getPageData(orderVoList, current, pageSize));
        return RespResult.success("获取订单列表成功", new PageResult<List<OrderVo>>(current, pageSize, orderVoList.size(), pageCnt, orderVoList));
    }

    @PostMapping("/update")
    @ServerErrorCatch
    @StrNotNull
    @NotNull
    @RsaDe
    @IsLoginParam
    @Transactional
    public RespResult<Object> updateOrder(
            @RequestParam(AccountConst.ACCOUNT_PARAM_NAME)
            @StrNotNullParam @RsaDeParam
            String account,
            @NotNullParam
            Long orderId,
            @NotNullParam
            Integer status
    ) {
        Orders orders = new Orders();
        orders.setId(orderId);
        orders.setStatus(status);
        orders.setUpdateTime(new Date());
        boolean res = ordersService.updateById(orders);
        if (!res) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return RespResult.fail("订单信息更新失败");
        }
        List<OrderVo> orderVoList = ordersService.findAndCacheAll();
        if (Objects.isNull(orderVoList)) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return RespResult.fail("订单信息更新失败");
        }
        return RespResult.success("订单信息更新成功");
    }

    @PostMapping("/cancel")
    @ServerErrorCatch
    @StrNotNull
    @NotNull
    @RsaDe
    @IsLoginParam
    @Transactional
    public RespResult<Object> cancelOrder(
            @RequestParam(AccountConst.ACCOUNT_PARAM_NAME)
            @StrNotNullParam @RsaDeParam
            String account,
            @NotNullParam
            Long orderId,
            @NotNullParam
            Integer status
    ) {
        Orders orders = ordersService.getById(orderId);
        Product product = productService.getById(orders.getProductId());
        product.setSale(product.getSale() - orders.getNum());
        boolean res = productService.updateById(product);
        if (!res) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return RespResult.fail("取消订单失败");
        }
        ProductOptions productOptions = productOptionsService.getById(orders.getProductOptionId());
        productOptions.setStock(productOptions.getStock() + orders.getNum());
        res = productOptionsService.updateById(productOptions);
        if (!res) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return RespResult.fail("取消订单失败");
        }
        List<ProductVo> productVoList = productService.getAllAndCache();
        if (Objects.isNull(productVoList)) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return RespResult.fail("取消订单失败");
        }
        orders.setStatus(status);
        orders.setUpdateTime(new Date());
        res = ordersService.updateById(orders);
        if (!res) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return RespResult.fail("取消订单失败");
        }
        List<OrderVo> orderVoList = ordersService.findAndCacheAll();
        if (Objects.isNull(orderVoList)) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return RespResult.fail("取消订单失败");
        }
        return RespResult.success("取消订单成功");
    }

    @PostMapping("/delivery")
    @ServerErrorCatch
    @StrNotNull
    @NotNull
    @RsaDe
    @IsLoginParam
    @Transactional
    public RespResult<Object> deliveryOrder(
            @RequestParam(AccountConst.ACCOUNT_PARAM_NAME)
            @StrNotNullParam @RsaDeParam
            String account,
            @NotNullParam
            Long orderId,
            @NotNullParam
            Integer status,
            @StrNotNullParam @RsaDeParam
            String logistics
    ) {
        Orders orders = new Orders();
        orders.setId(orderId);
        orders.setStatus(status);
        orders.setLogistics(logistics);
        orders.setUpdateTime(new Date());
        boolean res = ordersService.updateById(orders);
        if (!res) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return RespResult.fail("订单信息更新失败");
        }
        List<OrderVo> orderVoList = ordersService.findAndCacheAll();
        if (Objects.isNull(orderVoList)) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return RespResult.fail("订单信息更新失败");
        }
        return RespResult.success("订单信息更新成功");
    }

}
